﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using MpSoft.Basic.Configuration;

namespace MpSoft.Basic.Utils
{
    public class CommonHelper
    {
        #region Methods
        /// <summary>
        /// Verifies that a string is in valid e-mail format
        /// </summary>
        /// <param name="Email">Email to verify</param>
        /// <returns>true if the string is a valid e-mail address and false if it's not</returns>
        public static bool IsValidEmail(string Email)
        {
            return Regex.IsMatch(Email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        public static void ResetForm(ControlCollection controls)
        {
            foreach (var c in controls)
            {
                if (c is TextBox)
                    (c as TextBox).Text = string.Empty;
                if (c is DropDownList)
                    (c as DropDownList).ClearSelection();
                ResetForm((c as Control).Controls);
            }
        }
        /// <summary>
        /// Gets query string value by name
        /// </summary>
        /// <param name="Name">Parameter name</param>
        /// <returns>Query string value</returns>
        public static string QueryString(string Name)
        {
            String result = String.Empty;
            if (HttpContext.Current != null && HttpContext.Current.Request.QueryString[Name] != null)
                result = HttpContext.Current.Request.QueryString[Name].ToString();
            return result;
        }
        public static string FillterChar(string str)
        {
            str = ConvertToUnUnicode(str);
            str = Regex.Replace(str, @"[^0-9a-zA-Z]+", "-");
            str = str.Replace(" ", "-");
            str = str.Replace("--", "-");
            str = str.Replace("?", "-");
            str = str.Replace("&", "-");
            str = str.Replace(",", "-");
            str = str.Replace(":", "-");
            str = str.Replace("!", "-");
            str = str.Replace("'", "-");
            str = str.Replace("\"", "-");
            str = str.Replace("%", "-");
            str = str.Replace("#", "-");
            str = str.Replace("$", "-");
            str = str.Replace("*", "-");
            str = str.Replace("`", "-");
            str = str.Replace("~", "-");
            str = str.Replace("@", "-");
            str = str.Replace("^", "-");
            str = str.Replace(".", "-");
            str = str.Replace("/", "-");
            str = str.Replace(">", "-");
            str = str.Replace("<", "-");
            str = str.Replace("[", "-");
            str = str.Replace("]", "-");
            str = str.Replace(";", "-");
            str = str.Replace("+", "-");
            str = str.Replace("(", "-");
            str = str.Replace(")", "-");
            str = str.Replace("\"", "-");
            while (str.Contains("--"))
                str = str.Replace("--", "-");
            while (str.Contains("__"))
                str = str.Replace("__", "_");
            return str.ToLower();
        }
        public static string ConvertToUnUnicode(string str)
        {
            if (string.IsNullOrEmpty(str)) return string.Empty;
            str = str.Trim();
            Regex regex = new Regex("\\p{IsCombiningDiacriticalMarks}+");
            string temp = str.Normalize(NormalizationForm.FormD);
            return regex.Replace(temp, String.Empty).Replace('\u0111', 'd').Replace('\u0110', 'D');
        }

        public static string CreateUrlKey(string str)
        {
            if (string.IsNullOrEmpty(str)) return string.Empty;
            str.Trim();
            str = FillterChar(str);
            while (str.Contains("-"))
                str = str.Replace("-", "");
            return str.ToLower();
        }

        /// <summary>
        /// Gets boolean value from query string 
        /// </summary>
        /// <param name="Name">Parameter name</param>
        /// <returns>Query string value</returns>
        public static bool QueryStringBool(string Name)
        {
            String resultStr = QueryString(Name).ToUpperInvariant();
            return (resultStr == "YES" || resultStr == "TRUE" || resultStr == "1");
        }

        /// <summary>
        /// Gets integer value from query string 
        /// </summary>
        /// <param name="Name">Parameter name</param>
        /// <returns>Query string value</returns>
        public static int QueryStringInt(string Name)
        {
            String resultStr = QueryString(Name).ToUpperInvariant();
            int result;
            Int32.TryParse(resultStr, out result);
            return result;
        }

        /// <summary>
        /// Selects item
        /// </summary>
        /// <param name="List">List</param>
        /// <param name="Value">Value to select</param>
        public static void SelectListItem(DropDownList List, object Value)
        {
            if (List.Items.Count != 0)
            {
                ListItem selectedItem = List.SelectedItem;
                if (selectedItem != null)
                    selectedItem.Selected = false;
                if (Value != null)
                {
                    selectedItem = List.Items.FindByValue(Value.ToString());
                    if (selectedItem != null)
                        selectedItem.Selected = true;
                }
            }
        }

        /// <summary>
        /// Gets server variable by name
        /// </summary>
        /// <param name="Name">Name</param>
        /// <returns>Server variable</returns>
        public static string ServerVariables(string Name)
        {
            string tmpS = String.Empty;
            try
            {
                if (HttpContext.Current.Request.ServerVariables[Name] != null)
                {

                    tmpS = HttpContext.Current.Request.ServerVariables[Name].ToString();

                }
            }
            catch
            {
                tmpS = String.Empty;
            }
            return tmpS;
        }

        /// <summary>
        /// Gets a value indicating whether requested admin page
        /// </summary>
        public static bool IsAdmin()
        {
            return GetThisPageName().ToLowerInvariant().Contains("admincp/");
        }

        /// <summary>
        /// Gets this page name
        /// </summary>
        /// <returns></returns>
        public static string GetThisPageName()
        {
            string path = CommonHelper.ServerVariables("SCRIPT_NAME");
            if (path == null)
                path = string.Empty;
            return path;
        }

        /// <summary>
        /// Gets store location
        /// </summary>
        /// <param name="UseSSL">Try to use SSL</param>
        /// <returns>Store location</returns>
        public static string GetStoreHTTPLocation(bool UseSSL)
        {
            string s = "http://" + ServerVariables("HTTP_HOST") + HttpContext.Current.Request.ApplicationPath;
            if (!s.EndsWith("/"))
                s += "/";

            if (UseSSL)
            {
                s = s.Replace("http:/", "https:/");
                s = s.Replace("www.www", "www");
            }
            return s;
        }

        /// <summary>
        /// Sets cookie
        /// </summary>
        /// <param name="cookieName">Cookie name</param>
        /// <param name="cookieValue">Cookie value</param>
        /// <param name="ts">Timespan</param>
        public static void SetCookie(String cookieName, string cookieValue, TimeSpan ts)
        {
            try
            {
                HttpCookie cookie = new HttpCookie(cookieName);
                cookie.Value = HttpContext.Current.Server.UrlEncode(cookieValue);
                DateTime dt = DateTime.Now;
                cookie.Expires = dt.Add(ts);
                HttpContext.Current.Response.Cookies.Add(cookie);
            }
            catch (Exception exc)
            {
                //LogManager.InsertLog(LogTypeEnum.CustomerError, exc.Message, exc.ToString());
            }
        }

        /// <summary>
        /// Gets cookie string
        /// </summary>
        /// <param name="cookieName">Cookie name</param>
        /// <param name="decode">Decode cookie</param>
        /// <returns>Cookie string</returns>
        public static String GetCookieString(String cookieName, bool decode)
        {
            if (HttpContext.Current.Request.Cookies[cookieName] == null)
            {
                return String.Empty;
            }
            try
            {
                String tmp = HttpContext.Current.Request.Cookies[cookieName].Value.ToString();
                if (decode)
                    tmp = HttpContext.Current.Server.UrlDecode(tmp);
                return tmp;
            }
            catch
            {
                return String.Empty;
            }
        }

        /// <summary>
        /// Gets boolean value from cookie
        /// </summary>
        /// <param name="cookieName">Cookie name</param>
        /// <returns>Result</returns>
        public static bool GetCookieBool(String cookieName)
        {
            String tmpS = GetCookieString(cookieName, true).ToUpperInvariant();
            return (tmpS == "TRUE" || tmpS == "YES" || tmpS == "1");
        }

        /// <summary>
        /// Gets integer value from cookie
        /// </summary>
        /// <param name="cookieName">Cookie name</param>
        /// <returns>Result</returns>
        public static int GetCookieInt(String cookieName)
        {
            String tmpS = GetCookieString(cookieName, true);
            if (!String.IsNullOrEmpty(tmpS))
                return Convert.ToInt32(tmpS);
            else
                return 0;
        }

        /// <summary>
        /// IIF
        /// </summary>
        /// <param name="condition">Condition</param>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>Result</returns>
        static public int IIF(bool condition, int a, int b)
        {
            int x = 0;
            if (condition)
                x = a;
            else
                x = b;
            return x;
        }

        /// <summary>
        /// IIF
        /// </summary>
        /// <param name="condition">Condition</param>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>Result</returns>
        static public bool IIF(bool condition, bool a, bool b)
        {
            bool x = false;
            if (condition)
                x = a;
            else
                x = b;
            return x;
        }

        /// <summary>
        /// IIF
        /// </summary>
        /// <param name="condition">Condition</param>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>Result</returns>
        static public float IIF(bool condition, Single a, Single b)
        {
            float x = 0;
            if (condition)
            {
                x = a;
            }
            else
            {
                x = b;
            }
            return x;
        }

        /// <summary>
        /// IIF
        /// </summary>
        /// <param name="condition">Condition</param>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>Result</returns>
        static public double IIF(bool condition, double a, double b)
        {
            double x = 0;
            if (condition)
            {
                x = a;
            }
            else
            {
                x = b;
            }
            return x;
        }

        /// <summary>
        /// IIF
        /// </summary>
        /// <param name="condition">Condition</param>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>Result</returns>
        static public decimal IIF(bool condition, decimal a, decimal b)
        {
            decimal x = 0;
            if (condition)
            {
                x = a;
            }
            else
            {
                x = b;
            }
            return x;
        }

        /// <summary>
        /// IIF
        /// </summary>
        /// <param name="condition">Condition</param>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>Result</returns>
        static public string IIF(bool condition, String a, String b)
        {
            String x = String.Empty;
            if (condition)
            {
                x = a;
            }
            else
            {
                x = b;
            }
            return x;
        }

        /// <summary>
        /// Reloads current page
        /// </summary>
        public static void ReloadCurrentPage()
        {
            Uri currentUrl = HttpContext.Current.Request.Url;
            HttpContext.Current.Response.Redirect(currentUrl.ToString());
        }

        /// <summary>
        /// Decrypts text
        /// </summary>
        /// <param name="strCipherText">Cipher text</param>
        /// <returns>Decrypted string</returns>
        public string Decrypt_(string strCipherText)
        {
            string encryptionPrivateKey = MpConfig.EncryptionPrivateKey;
            TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
            UnicodeEncoding encoding = new UnicodeEncoding();
            ASCIIEncoding encoding2 = new ASCIIEncoding();
            byte[] buffer = Convert.FromBase64String(strCipherText);
            MemoryStream stream = new MemoryStream();
            MemoryStream stream2 = new MemoryStream(buffer);
            provider.Key = encoding2.GetBytes(encryptionPrivateKey.Substring(0, 16));
            provider.IV = encoding2.GetBytes(encryptionPrivateKey.Substring(8, 8));
            CryptoStream stream3 = new CryptoStream(stream2, provider.CreateDecryptor(), CryptoStreamMode.Read);
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(new StreamReader(stream3).ReadToEnd());
            writer.Flush();
            stream3.Clear();
            provider.Clear();
            return encoding.GetString(stream.ToArray());
        }

        /// <summary>
        /// Encrypts text
        /// </summary>
        /// <param name="strPlainText">Plaint text</param>
        /// <returns>Encrypted string</returns>
        public string Encrypt(string strPlainText)
        {
            string encryptionPrivateKey = MpConfig.EncryptionPrivateKey;
            TripleDESCryptoServiceProvider provider = new TripleDESCryptoServiceProvider();
            UnicodeEncoding encoding = new UnicodeEncoding();
            ASCIIEncoding encoding2 = new ASCIIEncoding();
            byte[] bytes = encoding.GetBytes(strPlainText);
            MemoryStream stream = new MemoryStream();
            provider.Key = encoding2.GetBytes(encryptionPrivateKey.Substring(0, 16));
            provider.IV = encoding2.GetBytes(encryptionPrivateKey.Substring(8, 8));
            CryptoStream stream2 = new CryptoStream(stream, provider.CreateEncryptor(), CryptoStreamMode.Write);
            stream2.Write(bytes, 0, bytes.Length);
            stream2.FlushFinalBlock();
            return Convert.ToBase64String(stream.ToArray());
        }

        /// <summary>
        /// Gets boolean value from NameValue collection
        /// </summary>
        /// <param name="config">NameValue collection</param>
        /// <param name="valueName">Name</param>
        /// <param name="defaultValue">Default value</param>
        /// <returns>Result</returns>
        internal static bool ConfigGetBooleanValue(NameValueCollection config, string valueName, bool defaultValue)
        {
            bool result;
            string str1 = config[valueName];
            if (str1 == null)
                return defaultValue;
            if (!bool.TryParse(str1, out result))
                throw new ProviderException(string.Format("Value must be boolean {0}", valueName));
            return result;
        }

        /// <summary>
        /// Gets integer value from NameValue collection
        /// </summary>
        /// <param name="config">NameValue collection</param>
        /// <param name="valueName">Name</param>
        /// <param name="defaultValue">Default value</param>
        /// <param name="zeroAllowed">Zero allowed</param>
        /// <param name="maxValueAllowed">Max value allowed</param>
        /// <returns>Result</returns>
        internal static int ConfigGetIntValue(NameValueCollection config, string valueName, int defaultValue, bool zeroAllowed, int maxValueAllowed)
        {
            int result;
            string str1 = config[valueName];
            if (str1 == null)
                return defaultValue;
            if (!int.TryParse(str1, out result))
            {
                if (zeroAllowed)
                {
                    throw new ProviderException(string.Format("Value must be non negative integer {0}", valueName));
                }
                throw new ProviderException(string.Format("Value must be positive integer {0}", valueName));
            }
            if (zeroAllowed && (result < 0))
                throw new ProviderException(string.Format("Value must be non negative integer {0}", valueName));
            if (!zeroAllowed && (result <= 0))
                throw new ProviderException(string.Format("Value must be positive integer {0}", valueName));
            if ((maxValueAllowed > 0) && (result > maxValueAllowed))
                throw new ProviderException(string.Format("Value too big {0}", valueName));
            return result;
        }

        #endregion
    }
}
